<?php

// +----------------------------------------------------------------------
// | OneThink [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013 http://www.onethink.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://www.zjzit.cn>
// +----------------------------------------------------------------------

/**
 * 把返回的数据集转换成Tree
 * @param array $list 要转换的数据集
 * @param string $pid parent标记字段
 * @param string $level level标记字段
 * @return array
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root = 0) {
// 创建Tree
    $tree = array();
    if (is_array($list)) {
// 创建基于主键的数组引用
        $refer = array();
        foreach ($list as $key => $data) {
            $refer[$data[$pk]] = & $list[$key];
        }
        foreach ($list as $key => $data) {
// 判断是否存在parent
            $parentId = $data[$pid];
            if ($root == $parentId) {
                $tree[] = & $list[$key];
            } else {
                if (isset($refer[$parentId])) {
                    $parent = & $refer[$parentId];
                    $parent[$child][] = & $list[$key];
                }
            }
        }
    }
    return $tree;
}

/**
 * 将list_to_tree的树还原成列表
 * @param  array $tree  原来的树
 * @param  string $child 孩子节点的键
 * @param  string $order 排序显示的键，一般是主键 升序排列
 * @param  array  $list  过渡用的中间数组，
 * @return array        返回排过序的列表数组
 * @author yangweijie <yangweijiester@gmail.com>
 */
function tree_to_list($tree, $child = '_child', $order = 'id', &$list = array()) {
    if (is_array($tree)) {
        $refer = array();
        foreach ($tree as $key => $value) {
            $reffer = $value;
            if (isset($reffer[$child])) {
                unset($reffer[$child]);
                tree_to_list($value[$child], $child, $order, $list);
            }
            $list[] = $reffer;
        }
        $list = list_sort_by($list, $order, $sortby = 'asc');
    }
    return $list;
}

/**
 * 格式化字节大小
 * @param  number $size      字节数
 * @param  string $delimiter 数字和单位分隔符
 * @return string            格式化后的带单位的大小
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function format_bytes($size, $delimiter = '') {
    $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
    for ($i = 0; $size >= 1024 && $i < 5; $i++)
        $size /= 1024;
    return round($size, 2) . $delimiter . $units[$i];
}

/**
 * 设置跳转页面URL
 * 使用函数再次封装，方便以后选择不同的存储方式（目前使用cookie存储）
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function set_redirect_url($url) {
    cookie('redirect_url', $url);
}

/**
 * 获取跳转页面URL
 * @return string 跳转页URL
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function get_redirect_url() {
    $url = cookie('redirect_url');
    return empty($url) ? __APP__ : $url;
}

/**
 * 时间戳格式化
 * @param int $time
 * @return string 完整的时间显示
 * @author huajie <banhuajie@163.com>
 * @since 1.1 <2015-8-6> SoChishun 新增字符串时间转换功能
 */
function time_format($time = NULL, $format = 'Y-m-d H:i') {
    if (!is_numeric($time)) {
        $time = strtotime($time);
    }
    $time = $time === NULL ? NOW_TIME : intval($time);
    return date($format, $time);
}

//基于数组创建目录和文件
function create_dir_or_files($files) {
    foreach ($files as $key => $value) {
        if (substr($value, -1) == '/') {
            mkdir($value);
        } else {
            @file_put_contents($value, '');
        }
    }
}

if (!function_exists('array_column')) {

    function array_column(array $input, $columnKey, $indexKey = null) {
        $result = array();
        if (null === $indexKey) {
            if (null === $columnKey) {
                $result = array_values($input);
            } else {
                foreach ($input as $row) {
                    $result[] = $row[$columnKey];
                }
            }
        } else {
            if (null === $columnKey) {
                foreach ($input as $row) {
                    $result[$row[$indexKey]] = $row;
                }
            } else {
                foreach ($input as $row) {
                    $result[$row[$indexKey]] = $row[$columnKey];
                }
            }
        }
        return $result;
    }

}

// =========================================================================================
// @author   sutroon <14507247@qq.com>
// @since 1.0 2014-6-24 by sutroon; 2.0 2014-12-22 by sutroon 重构函数命名,统一加前缀sofn_
// =========================================================================================
/**
 * 发送sokcet数据
 * @param string $in
 * @param string $ip
 * @param int $port
 * @return string
 * @since 1.0 2014-08-14 by kerry
 * @example socket_send($tsid . ',' . $state)
 */
function sofn_socket_send($in, $ip = '', $port = 8855) {
    if (!$ip) {
        $ip = $_SERVER['SERVER_NAME'];
    }
    error_reporting(E_ALL);
    set_time_limit(0);
    $fp = stream_socket_client("udp://$ip:$port", $errno, $errstr);
// echo 'stream_socket_client("udp://'.$ip.':'.$port.'", $errno, $errstr)';
    if (!$fp) {
        return "ERROR: $errno - $errstr";
    } else {
        fwrite($fp, $in);
        return fread($fp, 26);
        fclose($fp);
    }
}

/**
 * 合并数组为字符串
 * 
 * @param string $glue 合并符号
 * @param array $arr 数组
 * @param int $start 开始索引
 * @param int $end 结束索引
 * @return string
 * @since 1.0 2015-2-7 by sutroon
 * @example sofn_array_implode('|', $item, 4)
 */
function sofn_array_implode($glue, $arr, $start = 0, $end = 0) {
    if ($end > 0) {
        $len = count($arr);
        if ($end >= $len) {
            $end = $len - 1;
        }
    }
    if ($start > 0 && $end > 0 && $start > $end) {
        $start = $end;
    }
    $i = 0;
    $str = '';
    foreach ($arr as $key => $value) {
        if ($start > 0 && $i < $start) {
            $i++;
            continue;
        }
        if ($end > 0 && $i > $end) {
            break;
        }
        $str .= $glue . $value;
        $i++;
    }
    return $str ? substr($str, 1) : $str;
}

/**
 * 字符串截取，支持中文和其他编码
 * @param string $str 需要转换的字符串
 * @param string $start 开始位置
 * @param string $length 截取长度 默认null
 * @param string $suffix 截断显示字符 默认false
 * @param string $charset 编码格式 默认utf-8
 * @return string
 * @since 1.0 <2015-4-3> SoChishun Refactoring by \Org\Util\String::msubstr
 * @since 1.1 <2015-4-21> SoChishun 新增缩略号自动长度判断逻辑
 */
function sofn_msubstr($str, $start = 0, $length = NULL, $suffix = false, $charset = "utf-8") {
    if (function_exists("mb_substr"))
        $slice = mb_substr($str, $start, is_null($length) ? mb_strlen($str, $charset) - $start : $length, $charset);
    elseif (function_exists('iconv_substr')) {
        $slice = iconv_substr($str, $start, is_null($length) ? iconv_strlen($str, $charset) - $start : $length, $charset);
    } else {
        $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        $slice = join("", array_slice($match[0], $start, $length));
    }
    if ($suffix && strlen($slice) < strlen($str)) {
        $slice.=true === $suffix ? '...' : $suffix;
    }
    return $slice;
}

/**
 * 绝对路径转相对路径
 * @param string $path
 * @return string
 * @since 1.0 <2015-10-9> SoChishun Added.
 */
function sofn_path_ator($path) {
    $root = $_SERVER['DOCUMENT_ROOT'];
    $path = substr($path, strlen($root));
    if ('/' != DIRECTORY_SEPARATOR) {
        $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
    }
    return $path;
}

/**
 * 相对路径转绝对路径
 * @param string $path
 * @return string
 * @since 1.0 <2015-10-9> SoChishun Added.
 */
function sofn_path_rtoa($path) {
    $root = $_SERVER['DOCUMENT_ROOT'];
    if ('/' != DIRECTORY_SEPARATOR) {
        $path = str_replace('/', DIRECTORY_SEPARATOR, $path);
    }
    return $root . $path;
}

/**
 * 重命名路径中的文件名
 * <br />用户生成缩略图路径
 * @param type $path
 * @param type $prefix
 * @param type $sufix
 * @return type
 * @since 1.0 <2015-11-02> SoChishun Added.
 */
function sofn_rename_file($path, $prefix = 's_', $sufix = '') {
    $pathinfo = pathinfo($path);
    return $pathinfo['dirname'] . '/' . $prefix . $pathinfo['filename'] . $sufix . '.' . $pathinfo['extension'];
}

/**
 * 返回指定路径下的内容
 * @param string $directory 相对路径
 * @param array $config 选项
 * @return array
 * @throws Exception
 * @since 1.0 <2015-5-11> SoChishun Added.
 * @since 1.1 <2015-10-8> SoChishun 新增filetype文件类别属性
 */
function sofn_read_dir($directory, $options = array()) {
    $config = array('name' => true, 'path' => true, 'real_path' => true, 'relative_path' => false, 'exten' => false, 'ctime' => false, 'mtime' => false, 'size' => false, 'is_dir' => true, 'is_file' => false, 'is_link' => false, 'is_executable' => false, 'is_readable' => false, 'is_writable' => false, 'filetype' => false);
    if ($options) {
        $config = array_merge($config, $options);
    }
    try {
        $dir = new DirectoryIterator(sofn_path_rtoa($directory));
    } catch (Exception $e) {
        throw new Exception($directory . ' is not readable');
    }
    // 文件分类
    $filetypes = array('zip' => array('zip', 'rar', '7-zip', 'tar', 'gz', 'gzip'), 'doc' => array('txt', 'rtf', 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'wps', 'et'), 'script' => array('php', 'js', 'css', 'c'), 'image' => array('jpg', 'jpeg', 'png', 'gif', 'tiff', 'psd', 'bmp', 'ico'));
    $files = array();
    foreach ($dir as $file) {
        if ($file->isDot()) {
            continue;
        }
        if ($config['name']) {
            $item['name'] = $file->getFileName();
        }
        if ($config['path']) {
            $item['path'] = $file->getPath();
        }
        if ($config['real_path']) {
            $item['real_path'] = $file->getRealPath();
        }
        if ($config['relative_path']) {
            $item['relative_path'] = sofn_path_ator($file->getRealPath());
        }
        $exten = $file->getExtension();
        if ($config['exten']) {
            $item['exten'] = $exten;
        }
        if ($config['filetype']) {
            $scategory = '';
            foreach ($filetypes as $catetory => $extens) {
                if (in_array($exten, $extens)) {
                    $scategory = $catetory;
                    break;
                }
            }
            $item['filetype'] = $scategory;
        }
        if ($config['mtime']) {
            $item['mtime'] = $file->getMTime();
        }
        if ($config['ctime']) {
            $item['ctime'] = $file->getCTime();
        }
        if ($config['size']) {
            $item['size'] = $file->getSize();
        }
        if ($config['is_dir']) {
            $item['is_dir'] = $file->isDir();
        }
        if ($config['is_file']) {
            $item['is_file'] = $file->isFile();
        }
        if ($config['is_link']) {
            $item['is_link'] = $file->isLink();
        }
        if ($config['is_executable']) {
            $item['is_executable'] = $file->isExecutable();
        }
        if ($config['is_readable']) {
            $item['is_readable'] = $file->isReadable();
        }
        if ($config['is_writable']) {
            $item['is_writable'] = $file->isWritable();
        }
        $files[] = $item;
    }
    return $files;
}
